# -*- coding:utf-8 -*-

import json
import logging
import os
import platform
import subprocess
import psutil
import requests
import threading
import configparser as cp  # python3

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
config = cp.ConfigParser()
config.read(BASE_DIR + '/conf/config.cfg')

log_file = config.get('config', 'log_file')
pid_file = config.get('config', 'pid_file')
token = config.get('config', 'token')
server_ip = config.get('config', 'server')
server_url = config.get('config', 'url')


def get_os_info():
    """
    获取操作系统信息
    """
    cmd = 'dmidecode'
    p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    stdout, stderr = p.communicate()
    s_stdout = str(stdout)
    return s_stdout


def parser_os_info(os_data):
    """
    解析获取到的操作系统信息
    """
    data = {}
    line_in = False
    for line in os_data.strip("b").strip("'").strip('\\n').split('\\n'):
        if line.startswith('System Information'):
            line_in = True
            continue
        if line.startswith('\\t') and line_in:
            j, v = [i.strip() for i in line.split(':')]
            k = j.strip('\\t')
            data[k] = v
        else:
            line_in = False
    return data


def get_server_type():
    """
    获取服务器类型
    """
    host_cmd = 'systemd-detect-virt'
    vm_cmd = 'systemd-detect-virt -v'
    con_cmd = 'systemd-detect-virt -c'
    host = subprocess.Popen(host_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    host_out, host_err = host.communicate()
    vm = subprocess.Popen(vm_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    vm_out, vm_err = vm.communicate()
    container = subprocess.Popen(con_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    con_out, con_err = container.communicate()
    s_host_out = host_out.decode('utf-8').strip().lower()
    s_vm_out = vm_out.decode('utf-8').strip().lower()
    s_con_out = con_out.decode('utf-8').strip().lower()
    if s_host_out == 'none':  # 有输出则判断为物理机
        return '1'
    if s_vm_out != 'none':  # 有输出则判断为虚拟机
        return '2'
    if s_con_out != 'none':  # 有输出则判断为容器
        return '3'


def get_cpu_info():
    """
    获取cpu信息
    """
    cpu_info = dict()
    cmd = "cat /proc/cpuinfo | grep 'model name' | head -1"
    p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    cpu_out, cpu_err = p.communicate()
    s_cpu_out = cpu_out.decode('utf-8').strip().split(':')[1].strip()
    cpu_info['cpu_mode'] = s_cpu_out
    cpu_info['cpu_count'] = psutil.cpu_count()
    cpu_info['cpu_core_count'] = psutil.cpu_count(logical=False)
    return cpu_info


def get_memory_info():
    """
    获取内存大小信息
    """
    mem_info = dict()
    cmd = "cat /proc/meminfo | grep 'MemTotal'"
    p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
    mem_our, mem_err = p.communicate()
    s_mem_our = mem_our.decode('utf-8').strip().split(':')[1].strip()
    mem_info['total_memory'] = s_mem_our
    return mem_info


def get_disk_info():
    """
    获取硬盘信息
    """
    disk_info = dict()
    ret = []
    cmd = "fdisk -l | egrep '^Disk\s/dev/[a-z]+:\s\w*'"
    p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    b_stdout, stderr = p.communicate()
    s_stdout = b_stdout.decode('utf-8').strip().split('\n')
    for i in s_stdout:
        j = i.split(",")
        if j[0]:
            ret.append(j[0])
    for i in ret:
        k = i.split(':')[0].split()[1].strip()
        for j in ret:
            v = j.split(':')[1].strip()
            disk_info[k] = v
    return disk_info


def get_nic_info():
    """
    获取网络信息
    """
    nic_dict = dict()
    data = psutil.net_if_addrs()
    nic_name = list(data.keys())
    for i in nic_name:
        s_addr_lst = list()
        ipv4_lst = list()
        ipv6_lst = list()
        for j in data[i]:
            s_addr = str(j).strip('snicaddr(').strip(')').split(',')
            s_dict = dict()
            ip_dict = dict()
            for s in s_addr:
                k, v = [i.strip().strip("'") for i in s.split('=')]
                s_dict[k] = v
            if s_dict['family'] == '<AddressFamily.AF_INET: 2>':
                ip_dict['family'] = 'ipv4'
                ip_dict['address'] = s_dict['address']
                ip_dict['netmask'] = s_dict['netmask']
                ipv4_lst.append(s_dict['address'])
            elif s_dict['family'] == '<AddressFamily.AF_INET6: 10>':
                ip_dict['family'] = 'ipv6'
                ip_dict['address'] = s_dict['address']
                ip_dict['netmask'] = s_dict['netmask']
                ipv6_lst.append(s_dict['address'])
            elif s_dict['family'] == '<AddressFamily.AF_PACKET: 17>':
                ip_dict['family'] = 'mac'
                ip_dict['address'] = s_dict['address']
            else:
                continue
            s_addr_lst.append(ip_dict)
        s_addr_lst.append(ipv4_lst)
        s_addr_lst.append(ipv6_lst)
        nic_dict[i] = s_addr_lst
    return nic_dict


def get_pid():
    """
    把pid写入到文件
    """
    pid = str(os.getpid())
    with open(BASE_DIR + pid_file, 'w+') as fp:
        fp.write(pid)


def collect_into():
    data_info = dict()
    # 系统信息
    data_info['asset_sn'] = parser_os_info(get_os_info())['Serial Number']
    data_info['asset_type'] = get_server_type()
    data_info['vendor'] = parser_os_info(get_os_info())['Manufacturer']
    data_info['hostname'] = platform.node()
    data_info['created_by'] = '1'
    # cpu
    data_info['cpu_mode'] = get_cpu_info()['cpu_mode']
    data_info['cpu_count'] = get_cpu_info()['cpu_count']
    data_info['cpu_core_count'] = get_cpu_info()['cpu_core_count']
    # memory
    data_info['total_memory'] = get_memory_info()['total_memory']
    # disk
    data_info['disk_info'] = get_disk_info()
    data_info['nic_info'] = get_nic_info()
    data_info['ser_model'] = parser_os_info(get_os_info())['Product Name']
    data_info['os_type'] = platform.system()
    data_info['os_release'] = platform.linux_distribution()[0] + " " + platform.linux_distribution()[
        1] + " " + platform.machine()
    data_info['os_distribution'] = platform.linux_distribution()[0]
    data_info['token'] = token
    return json.dumps(data_info)


def asset_info_post():
    """
    发送数据到服务器
    """
    url = "http://{ip}{url}".format(ip=server_ip, url=server_url)
    try:
        res = requests.post(url, collect_into())
        if res.text:
            logging.info(res.text)
        else:
            logging.info("Server return http status code: {code}".format(code=res.status_code))
    except Exception as msg:
        logging.info(msg)
    return True


def log():
    logging.basicConfig(level=logging.INFO,
                        format='%(asctime)s | %(levelname)s | %(filename)s | %(funcName)s | %(message)s',
                        datefmt='%Y%m%d %H:%M:%S',
                        filename=log_file,
                        filemode='ab+')
    return logging.basicConfig


def clean_log():
    os.system("> {logfile}".format(logfile=log_file))
    logging.info("clean agent log")


def run_threaded(job_func):
    job_thread = threading.Thread(target=job_func)
    job_thread.start()


if __name__ == '__main__':
    asset_info_post()
